package com.caregiver.watch.business.care.service.impl;

import com.caregiver.watch.business.care.dao.UserPackageOrderDao;
import com.caregiver.watch.business.care.enums.PackageEffectivenessStatusEnum;
import com.caregiver.watch.business.care.enums.PackageTypeEnum;
import com.caregiver.watch.business.care.model.po.UserPackageOrder;
import com.caregiver.watch.business.care.service.UserPackageOrderService;
import com.caregiver.watch.common.utils.number.IntegerUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.caregiver.watch.business.care.enums.PackageEffectivenessStatusEnum.EFFECTIVE;
import static com.caregiver.watch.common.constant.NumberConstants.ONE;
import static com.caregiver.watch.common.constant.NumberConstants.TEN;
import static com.caregiver.watch.common.constant.NumberConstants.THIRTY;
import static com.caregiver.watch.common.constant.NumberConstants.TWELVE;
import static com.caregiver.watch.common.constant.NumberConstants.ZERO;

/**
 * @Description: 用户套餐购买订单服务
 * @Author 疆戟
 * @Date 2025/10/19 16:32
 * @Version 1.0
 */
@AllArgsConstructor
@Service
@Slf4j
 public class UserPackageOrderServiceImpl implements UserPackageOrderService {

    private final UserPackageOrderDao userPackageOrderDao;

    @Override
    public List<UserPackageOrder> queryEffectiveOrders(Long userId) {
        if (Objects.isNull(userId)) {
            return new ArrayList<>();
        }
        return userPackageOrderDao.selectEffectiveOrders(userId);
    }

    @Override
    public UserPackageOrder queryEffectiveOrder(Long userId) {
        if (Objects.isNull(userId)) {
            return null;
        }
        List<UserPackageOrder> userPackageOrders = userPackageOrderDao.selectEffectiveOrders(userId);
        if (CollectionUtils.isEmpty(userPackageOrders)) {
            return null;
        }
        return userPackageOrders.stream().filter(order -> {
            PackageTypeEnum packageType = order.getPackageType();
            if (Objects.isNull(packageType)) {
                return false;
            }
            // 生效中的套餐
            return EFFECTIVE == packageType.getEffectiveStatus(order);
        }).findFirst().orElse(null);
    }

    @Override
    public boolean saveOrder(UserPackageOrder order) {
        if (Objects.isNull(order)) {
            return false;
        }
        return userPackageOrderDao.insert(order) > ZERO;
    }

    @Override
    public UserPackageOrder queryPendingPaymentOrder(String orderNo) {
        if (Objects.isNull(orderNo)) {
            return null;
        }
        return userPackageOrderDao.queryPendingPaymentOrder(orderNo);
    }

    @Override
    public Boolean updatePaymentInfo(Long id, String payNo, BigDecimal payAmount, LocalDateTime payTime) {
        log.info("更新订单支付信息: {} payNo:{} 支付金额:{} 支付时间:{}", id, payNo, payAmount, payTime);
        if (Objects.isNull(id) || StringUtils.isBlank(payNo) || Objects.isNull(payAmount) || Objects.isNull(payTime)) {
            return Boolean.FALSE;
        }
        return userPackageOrderDao.updatePaymentInfo(id, payNo, payAmount, payTime) > ZERO;
    }

    @Override
    public Boolean deductWarningCount(Long userId, Integer count) {
        if (Objects.isNull(userId) || Objects.isNull(count) || count < ONE) {
            return Boolean.FALSE;
        }
        UserPackageOrder userPackageOrder = queryEffectiveOrder(userId);
        if (Objects.isNull(userPackageOrder)) {
            log.error("[扣减预警次数] 未查询到有效套餐订单，用户ID：{}", userId);
            return Boolean.FALSE;
        }
        PackageTypeEnum packageType = userPackageOrder.getPackageType();
        Integer oldWarningCount = userPackageOrder.getWarningCount();
        Integer newWarningCount = oldWarningCount + count;
        // 如果类型是次数 需要比较次数是否会大于套餐的次数
        if (PackageTypeEnum.COUNT == packageType && newWarningCount > IntegerUtils.ofNullable(userPackageOrder.getPackageValue())) {
            log.error("[扣减预警次数] 扣减的次数超出套餐的次数，用户ID：{} newWarningCount：{}", userId, newWarningCount);
            return Boolean.FALSE;
        }
        // 循环尝试
        int maxCount = THIRTY;
        do {
            boolean success = userPackageOrderDao.deductWarningCount(userId, userPackageOrder.getId(), oldWarningCount, newWarningCount) > ZERO;
            if (success) {
                return Boolean.TRUE;
            }
            // 查询最新的次数
            oldWarningCount = userPackageOrderDao.queryWarningCount(userId, userPackageOrder.getId());
            newWarningCount = oldWarningCount + count;
            // 如果类型是次数 需要比较次数是否会大于套餐的次数
            if (PackageTypeEnum.COUNT == packageType && newWarningCount > IntegerUtils.ofNullable(userPackageOrder.getPackageValue())) {
                log.error("[扣减预警次数] 扣减的次数超出套餐的次数，用户ID：{} newWarningCount：{}", userId, newWarningCount);
                return Boolean.FALSE;
            }
        } while (--maxCount > ZERO);
        log.error("[扣减预警次数] 尝试次数超出最大次数，用户ID：{} newWarningCount：{}", userId, newWarningCount);
        return Boolean.FALSE;
    }
}
